//
//  WmcWatermarkUtil.swift
//  YPWatermarkCamera
//
//  Created by Json on 2023/7/27.
//

import UIKit
import YPBedrock

struct WmcWatermarkUtil {
    
    /// 二维码图片元组(原始二维码和验证二维码)
    typealias QRCodeImageResult = (qrImage: UIImage?, qrVerImage: UIImage?)

    /// 方位角转描述
    static func azimuthAngleDefaultDescribe(_ angle: Double) -> String {
        var prefix = "未知"
        switch angle {
        case 330.0 ..< 360.0,
             0.0 ..< 30.0: prefix = "北"
        case 30.0 ..< 60.0: prefix = "东北"
        case 60.0 ..< 120.0: prefix = "东"
        case 120.0 ..< 150.0: prefix = "东南"
        case 150.0 ..< 210.0: prefix = "南"
        case 210.0 ..< 240.0: prefix = "西南"
        case 240.0 ..< 300.0: prefix = "西"
        case 300.0 ..< 330.0: prefix = "西北"
        default: break
        }
        let angleString = String(format: "%.2f", angle)
        let describe = "\(prefix)  \(angleString)°"
        return describe
    }
    /// 噪音分贝描述
    static func describeDBStr(for decibe: Double) -> String {
        var describe = ""
        let positiveDB = Int(decibe + 120) - 40
        switch positiveDB {
        case 0 ..< 20:
            describe = "很静"
        case 20 ..< 40:
            describe = "安静"
        case 40 ..< 60:
            describe = "正常"
        case 60 ..< 80:
            describe = "吵闹"
        case 80 ..< 100:
            describe = "很吵"
        case 100 ..< 120:
            describe = "无法忍受"
        default: break
        }
        return "\(positiveDB)分贝（\(describe)）"
    }
    
    
    /// 根据二维码图片生成二维码验证图
    /// - Parameters:
    ///   - qrImage: 二维码图片
    ///   - qrcodeView: 二维码验证控件
    static func makeQRVerImage(with qrImage: UIImage?, qrcodeView: WmcQRCodeVerifyView) -> UIImage? {
        guard let qrImage = qrImage else { return nil }
        // 期望的二维码显示大小(最低大小)
        let expireW = qrImage.size.width
        // 二维码控件宽高
        let qrcodeViewSize = qrcodeView.size(with: expireW)
        // 截图
        guard qrcodeViewSize.width > 0 && qrcodeViewSize.height > 0 else { return nil }
        UIGraphicsBeginImageContextWithOptions(CGSize(width: qrcodeViewSize.width, height: qrcodeViewSize.height), false, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        qrcodeView.image = qrImage
        // 设置控件大小
        qrcodeView.frame.size = qrcodeViewSize
        // 截图
        qrcodeView.layer.render(in: context)
        let qrVerImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return qrVerImage
    }
    
    /// 根据水印信息和二维码验证控件生成二维码验证图片
    /// - Parameters:
    ///   - watermarkModel: 水印信息
    ///   - qrcodeView: 二维码验证控件
    static func makeQRImageResult(with watermarkModel: WmcWatermarkDetailModel, qrcodeView: WmcQRCodeVerifyView?) -> QRCodeImageResult {
        guard let qrcodeView = qrcodeView,
              let qrImage = makeQRCodeImage(with: watermarkModel) else {
            return (nil, nil)
        }
        // 生成二维码验证图片
        guard let qrVerImage = WmcWatermarkUtil.makeQRVerImage(with: qrImage, qrcodeView: qrcodeView) else {
            return (qrImage, nil)
        }
        return (qrImage, qrVerImage)
    }
    
    /// 根据水印信息生成二维码
    static func makeQRCodeImage(with watermarkModel: WmcWatermarkDetailModel) -> UIImage? {
        let baseURL = YPWmcManager.shared.environmentType.baseWebURL
        let query = makeWatermarkInfo(with: watermarkModel)
//        WmcDebug("编码前参数长度: \(query.count)")
//        query = query.yp.urlEncoded ?? ""
//        WmcDebug("编码后参数长度: \(query.count)")
        let url = "\(baseURL)/wartermark-verify/index.html?data=\(query)"
        WmcDebug("二维码信息=====>\(url)")
        let qrcodeImage = WmcQRCodeUtil.createQRCodeImage(with: url, inputCorrection: .low)
        return qrcodeImage
    }
    
    /// 获取水印信息json数据
    /// - Parameter model: 水印信息模型
    static func makeWatermarkInfo(with model: WmcWatermarkDetailModel) -> String {
        let staticData = model.staticData
        // 地址信息
        let address = staticData.drawStaticAddress ?? WmcLocationManager.shared.poiStatus.value?.data
        // POI位置信息
        let geoPoint = address?.poi.location
        // 定位信息
        let location = WmcLocationManager.shared.locationStatus.value?.data?.location

        var infos: [[String: String]] = []
        model.fields.forEach { field in
            if !field.isOpen { return }
            var value: String = ""
            switch field.fieldType {
            case .title: // 标题
                value = field.content
            case .time: // 时间
                let date = WmcDateManager.shared.networkDate.value
                if let date = date {
                    let week = date.yp.weekNameCN
                    value = (date - 8.yp.hour).yp.string("yyyy年MM月dd日 \(week) HH时mm分ss秒")
                    WmcDebug("日期==>\(date)==>\(value)")
                }
            case .addr: // 地址
                if let address = address{
                    let prefix = address.addressPrefix ?? ""
                    let name = address.poi.name ?? ""
                    value = prefix + name
                }
            case .weather: // 天气
                let weather = WmcWeatherManager.share.weather.value
                if let weather = weather,
                   let live = weather.lives?.first {
                    value = "\(live.weather ?? "") \(live.temperature ?? "")℃"
                }
            case .lat: // 经纬度
                if let geoPoint = geoPoint {
                    value = "N \(geoPoint.latitude)°, E \(geoPoint.longitude)°"
                }
            case .altitude: // 海拔
                if let location = location {
                    value = String(format: "%.2f米", location.altitude)
                }
            case .azimuth: // 方位角
                let azimuth = WmcCLLocationManager.shared.azimuthAngleRelay.value
                value = WmcWatermarkUtil.azimuthAngleDefaultDescribe(azimuth)
            case .decibe: // 噪音分贝
                let decibe = WmcDecibeManager.shared.decibeRelay.value
                value = WmcWatermarkUtil.describeDBStr(for: decibe)
            case .speed: // 速度
                if let location = location {
                    value = String(format: "%.2f 米/秒", location.speed)
                }
            case .remark, .record, .text, .custom:
                value = field.content
            default: break
            }
            let key = field.title
            if !key.isEmpty && !value.isEmpty {
                var info: [String: String] = [:]
                info["k"] = key
                info["v"] = value
                infos.append(info)
            }
        }
        guard let data = try? JSONSerialization.data(withJSONObject: infos, options: .fragmentsAllowed) else {
            return ""
        }
        let query = String.init(data: data, encoding: .utf8) ?? ""
        return query
    }
    
    
    /// 根据原图,水印图,二维码图合成照片
    /// - Parameters:
    ///   - standardImage: 原图
    ///   - watermarkImage: 水印图
    ///   - qrVerImage: 二维码验证图
    static func makeImage(standardImage: UIImage, watermarkImage: UIImage, qrVerImage: UIImage?) -> UIImage? {
        guard standardImage.size.width > 0 && standardImage.size.height > 0 else { return nil }
        UIGraphicsBeginImageContextWithOptions(standardImage.size, false, standardImage.scale)
        let drawRect = CGRect(origin: .zero, size: standardImage.size)
        standardImage.draw(in: drawRect)
        watermarkImage.draw(in: drawRect)
        if let qrVerImage = qrVerImage {
            // 二维码图片大小
            let qr_width = qrVerImage.size.width
            let qr_height = qrVerImage.size.height
            WmcDebug("认证二维码实际大小:\(qr_width)-\(qr_height)")
            // 缩放比例
            let scale = standardImage.size.width / watermarkImage.size.width
            // 间距
            let margin = 16.0.wmc_autoHor
            let y = margin * scale
            let x = standardImage.size.width - margin * scale - qr_width * scale
            let rect = CGRect(x: x, y: y, width: qr_width * scale, height: qr_height * scale)
            qrVerImage.draw(in: rect)
        }
        let drawWatermarkImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return drawWatermarkImage
    }

}
